Chapter 2 Descriptive Analysis

2.1 Load packages

2.1.1 Load basic package

library(sp)
library(sf)
## Linking to GEOS 3.8.1, GDAL 3.1.1, PROJ 6.3.1
library(rgeos)
## rgeos version: 0.5-5, (SVN revision 640)
##  GEOS runtime version: 3.8.1-CAPI-1.13.3 
##  Linking to sp version: 1.4-2 
##  Polygon checking: TRUE
library(tmap)
library(tmaptools)
library(maptools)
## Checking rgeos availability: TRUE
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
## ✓ ggplot2 3.3.2     ✓ purrr   0.3.4
## ✓ tibble  3.0.4     ✓ dplyr   1.0.2
## ✓ tidyr   1.1.2     ✓ stringr 1.4.0
## ✓ readr   1.4.0     ✓ forcats 0.5.0
## ── Conflicts ────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(spdep)
## Loading required package: spData
## To access larger datasets in this package, install the spDataLarge package with:
## `install.packages('spDataLarge', repos='https://nowosad.github.io/drat/', type='source')`
library(janitor)
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library(rgdal)
## rgdal: version: 1.5-17, (SVN revision 1070)
## Geospatial Data Abstraction Library extensions to R successfully loaded
## Loaded GDAL runtime: GDAL 3.1.1, released 2020/06/22
## Path to GDAL shared files: /Library/Frameworks/R.framework/Versions/4.0/Resources/library/rgdal/gdal
## GDAL binary built with GEOS: TRUE 
## Loaded PROJ runtime: Rel. 6.3.1, February 10th, 2020, [PJ_VERSION: 631]
## Path to PROJ shared files: /Library/Frameworks/R.framework/Versions/4.0/Resources/library/rgdal/proj
## Linking to sp version:1.4-4
## To mute warnings of possible GDAL/OSR exportToProj4() degradation,
## use options("rgdal_show_exportToProj4_warnings"="none") before loading rgdal.

2.1.2 Load plot library

library(ggplot2)
library(RColorBrewer)

2.2 Load data

2.2.1 Load charge point registry.csv file

charge <- read_csv("datasets/national-charge-point-registry.csv")
## 
## ── Column specification ────────────────────────────────────────────────────────────────────────────
## cols(
##   .default = col_logical(),
##   chargeDeviceID = col_character(),
##   reference = col_character(),
##   name = col_character(),
##   latitude = col_double(),
##   longitude = col_double(),
##   buildingName = col_character(),
##   buildingNumber = col_character(),
##   thoroughfare = col_character(),
##   street = col_character(),
##   doubleDependantLocality = col_character(),
##   dependantLocality = col_character(),
##   town = col_character(),
##   county = col_character(),
##   postcode = col_character(),
##   countryCode = col_character(),
##   locationLongDescription = col_character(),
##   deviceManufacturer = col_character(),
##   deviceOwnerName = col_character(),
##   deviceOwnerWebsite = col_character(),
##   deviceOwnerTelephoneNo = col_character()
##   # ... with 69 more columns
## )
## ℹ Use `spec()` for the full column specifications.
## Warning: 15281 parsing failures.
## row         col   expected              actual                                          file
## 136 dateUpdated valid date 0000-00-00 00:00:00 'datasets/national-charge-point-registry.csv'
## 139 dateUpdated valid date 0000-00-00 00:00:00 'datasets/national-charge-point-registry.csv'
## 140 dateUpdated valid date 0000-00-00 00:00:00 'datasets/national-charge-point-registry.csv'
## 144 dateUpdated valid date 0000-00-00 00:00:00 'datasets/national-charge-point-registry.csv'
## 145 dateUpdated valid date 0000-00-00 00:00:00 'datasets/national-charge-point-registry.csv'
## ... ........... .......... ................... .............................................
## See problems(...) for more details.
summary(charge$chargeDeviceStatus)
##    Length     Class      Mode 
##     12332 character character

2.2.2 Load London wards shapefile

londonwards <- st_read("datasets/wards/London_Ward_CityMerged.shp") %>% 
  st_transform(., 27700)
## Reading layer `London_Ward_CityMerged' from data source `/Users/apple/OneDrive - University College London/Module assessment/CASA_project/casa_project/datasets/wards/London_Ward_CityMerged.shp' using driver `ESRI Shapefile'
## Simple feature collection with 625 features and 7 fields
## geometry type:  POLYGON
## dimension:      XY
## bbox:           xmin: 503568.2 ymin: 155850.8 xmax: 561957.5 ymax: 200933.9
## projected CRS:  OSGB 1936 / British National Grid

2.3 Filter data

chargepoints <- charge [charge$chargeDeviceStatus=="In service" & !is.na(charge$latitude) & !is.na(charge$longitude),] 

2.3.1 Function to filter year (2014, 2017, 2020 register)

filterfun <- function(end){
  enddate <- end
  
  filterpoints <- chargepoints %>% 
    filter(chargepoints$dateCreated<=enddate)
  return(filterpoints)
}

2.3.2 Function to transform projection & crop to London

londonPfun <- function(end){
  filteredpoints <- filterfun(end)
  transpoints <- filteredpoints %>% 
    select(., c(3,4,5)) %>% 
    st_as_sf(., coords = c("longitude", "latitude"),crs = 4326) %>% 
    st_transform(., 27700) %>%
    distinct()
  
  charge_london <- st_intersects(londonwards, transpoints)
  londonpoints <- transpoints[unlist(charge_london),]
  return(londonpoints)
}

2.3.3 Instance object

trend <- data.frame(date=c("2012", "2013", "2014", "2015", "2016",
                           "2017", "2018", "2019", "2020"),
                    count=c(nrow(londonPfun("2012-12-31")),nrow(londonPfun("2013-12-31")),
                            nrow(londonPfun("2014-12-31")),nrow(londonPfun("2015-12-31")),
                            nrow(londonPfun("2016-12-31")),nrow(londonPfun("2017-12-31")),
                            nrow(londonPfun("2018-12-31")),nrow(londonPfun("2019-12-31")),
                            nrow(londonPfun("2020-12-31"))))
ggplot(data = trend, mapping = aes(x = date, y = count, group = 1)) +
  geom_line(alpha = 0.7)+
  geom_point(alpha = 0.6)+
  geom_text(aes(label = count), vjust = "inward", hjust = "outward", size=3.5)+
  xlab("Year")+
  ylab("Number of charging points")+
  ggtitle("Trend of charging infrastructure deployment in London")+
  theme(axis.title = element_text(size=18),axis.text = element_text(size=16),
        strip.text = element_text(size=18))+
  labs(color = "Development trend")+
  theme_classic() 

ggsave("pic/charge points trend.jpg", width = 7, height = 4)
londonpoints2018 <- londonPfun("2018-12-31")
londonpoints2019 <- londonPfun("2019-12-31")
londonpoints2020 <- londonPfun("2020-12-31")

2.3.4 Function to map charge point density by wards

pointsjoinedfun <- function(londonpointsyear){
  londonpointsyear <- londonpointsyear
  charge_points_ward <- londonpointsyear[londonwards,]
  
  points_wards <- londonwards%>%
    st_join(charge_points_ward)%>%
    add_count(NAME)%>%
    janitor::clean_names()%>%
    #then density of the points per ward
    mutate(density=(n/hectares)*1000) %>% 
    mutate(id=1) %>% 
    mutate(sumpoints=aggregate(n~id,.,FUN=sum)) %>% 
    mutate(percentage=((n/sumpoints[1, 2]))*100) %>% 
    #select density and other variables 
    dplyr::select(density, percentage, name, gss_code, n) %>% 
    distinct(., gss_code, .keep_all = TRUE)
  
  points_wards <- points_wards %>%                    
    group_by(gss_code) %>%         
    summarise(density=density,
              percentage=percentage,
              wardname=name,
              chargepointcount=n)
  return(points_wards)
}

2.3.5 Save charge points by wards

points_wards <- pointsjoinedfun(londonpoints2020) %>% 
  st_drop_geometry()
## `summarise()` ungrouping output (override with `.groups` argument)
write.table(points_wards,"created datasets/points_wards.csv",row.names=FALSE,col.names=TRUE,sep=",")
densityfun <- function(londonpointsyear, number, mode){
  points_wards <- pointsjoinedfun(londonpointsyear)
  tmap_mode(mode)
  breaks = c(0, 20, 30, 40, 50, 60, 200, 400, +Inf) 
  tm <- tm_shape(points_wards) +
    tm_polygons("density",
                breaks=breaks,
                palette=RColorBrewer::brewer.pal(8, "YlOrRd"),
                midpoint=NA) +
    tm_legend(show=FALSE)+
    tm_layout(frame=FALSE)+
    tm_credits(number, position=c(0,0.85), size=1)
  
  return(tm)
}
legendfun <- function(londonpointsyear){
  points_wards <- pointsjoinedfun(londonpointsyear)
  
  breaks = c(0, 20, 30, 40, 50, 60, 200, 400, +Inf) 
  legend <- tm_shape(points_wards) +
    tm_polygons("density",
                breaks=breaks,
                palette=RColorBrewer::brewer.pal(8, "YlOrRd"), 
                title="Density of Charge Points in London \n(per thousand hectare)") +
    tm_scale_bar(position=c(0.4, 0.01), text.size=0.6)+
    tm_compass(north=0, position=c(0.75, 0.3))+
   
    tm_layout(title = "Charge Points Density Trend", 
              legend.title.size=1,
              legend.text.size = 0.6,
              legend.only = TRUE, 
              legend.position=c(0.1,0.1),asp=0.1)
  
  return(legend)
}

2.3.6 Tmap - charge point density by ward

tm1 <- densityfun(londonpoints2018, "a)", "plot")
## `summarise()` ungrouping output (override with `.groups` argument)
## tmap mode set to plotting
tm2 <- densityfun(londonpoints2019, "b)", "plot")
## `summarise()` ungrouping output (override with `.groups` argument)
## tmap mode set to plotting
tm3 <- densityfun(londonpoints2020, "c)", "plot")
## `summarise()` ungrouping output (override with `.groups` argument)
## tmap mode set to plotting
legend <- legendfun(londonpoints2020)
## `summarise()` ungrouping output (override with `.groups` argument)
t_density <- tmap_arrange(tm1, tm2, tm3, legend, ncol=2)
t_density

tmap_save(t_density, 'pic/london charge points density.png', width=7, height=4)
## Map saved to /Users/apple/OneDrive - University College London/Module assessment/CASA_project/casa_project/pic/london charge points density.png
## Resolution: 2100 by 1200 pixels
## Size: 7 by 4 inches (300 dpi)
tm1v <- densityfun(londonpoints2018, "a)", "view")
## `summarise()` ungrouping output (override with `.groups` argument)
## tmap mode set to interactive viewing
tm2v <- densityfun(londonpoints2019, "b)", "view")
## `summarise()` ungrouping output (override with `.groups` argument)
## tmap mode set to interactive viewing
tm3v <- densityfun(londonpoints2020, "c)", "view")
## `summarise()` ungrouping output (override with `.groups` argument)
## tmap mode set to interactive viewing
legend <- legendfun(londonpoints2020)
## `summarise()` ungrouping output (override with `.groups` argument)
t_densityv <- tmap_arrange(tm1v, tm2v, tm3v, ncol=1)
t_densityv
## Credits not supported in view mode.
## Credits not supported in view mode.
## Credits not supported in view mode.